﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Net;
using System.Net.Http;

namespace JsdlSampleApp
{
	public partial class Person : INotifyPropertyChanged
	{	
		private String firstName;
		[JsonProperty("firstName", Required = Required.Default)]
		public String FirstName
		{
			get { return firstName; }
			set 
			{
				if (value != firstName)
				{
					firstName = value; 
					OnPropertyChanged("FirstName");
				}
			}
		}
		
		private String lastName;
		[JsonProperty("lastName", Required = Required.Default)]
		public String LastName
		{
			get { return lastName; }
			set 
			{
				if (value != lastName)
				{
					lastName = value; 
					OnPropertyChanged("LastName");
				}
			}
		}
		
	
		public string ToJson() 
		{
			return JsonConvert.SerializeObject(this);
		}
	
		public static Person FromJson(string json)
		{
			return JsonConvert.DeserializeObject<Person>(json);
		}
		
		public event PropertyChangedEventHandler PropertyChanged;
	
		protected virtual void OnPropertyChanged(string propertyName = null)
		{
			PropertyChangedEventHandler handler = PropertyChanged;
			if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
		}
	}
	
	public partial class DataService
	{
		public string BaseUrl { get; set; }
		public Type[] Types { get { return new Type[] { typeof(Person) }; } }
	
		public class JsdlException : Exception
		{
			public JsdlException(string code, string message, string serverStackTrace) : base(message) { Code = code; ServerStackTrace = serverStackTrace; }
			public string Code { get; private set; }
			public string ServerStackTrace { get; private set; }
		}
	
		partial void PrepareRequest(HttpClient request);
	partial void ProcessResponse(HttpClient request, HttpResponseMessage response);
	
		public DataService() { }
		public DataService(string baseUrl)
		{
			BaseUrl = baseUrl; 
		}
	
		public async Task<decimal> SumAsync(decimal _a, decimal _b)
		{
			var url = BaseUrl + "/JsdlServices/DataService?operation=Sum&";
		
			var parameters = new List<object>();
			parameters.Add(_a);
			parameters.Add(_b);
		
			var content = new StringContent(JsonConvert.SerializeObject(parameters));
			
			var client = new HttpClient();
			PrepareRequest(client);
			var response = await client.PostAsync(url, content);
			ProcessResponse(client, response);
			var data = await response.Content.ReadAsStringAsync(); 
			var httpStatusCode = response.StatusCode;
			var isError = (int)httpStatusCode >= 400; 
			
				if (isError)
				{
					if (!string.IsNullOrEmpty(data))
					{
						try
						{
							var exception = (JContainer)JsonConvert.DeserializeObject(data);
							throw new JsdlException(
								exception["code"] != null ? exception["code"].ToString() : null, 
								exception["message"] != null ? exception["message"].ToString() : "", 
								exception["stackTrace"] != null ? exception["stackTrace"].ToString() : null);
						} catch { }
					}
					throw new JsdlException("http_" + (int)httpStatusCode, "HTTP error: " + httpStatusCode, null);
				}
			return JsonConvert.DeserializeObject<decimal>(data);
		}
		
		public async Task<Person> GetPersonAsync(long _id)
		{
			var url = BaseUrl + "/JsdlServices/DataService?operation=GetPerson&";
		
			var parameters = new List<object>();
			parameters.Add(_id);
		
			var content = new StringContent(JsonConvert.SerializeObject(parameters));
			
			var client = new HttpClient();
			PrepareRequest(client);
			var response = await client.PostAsync(url, content);
			ProcessResponse(client, response);
			var data = await response.Content.ReadAsStringAsync(); 
			var httpStatusCode = response.StatusCode;
			var isError = (int)httpStatusCode >= 400; 
			
				if (isError)
				{
					if (!string.IsNullOrEmpty(data))
					{
						try
						{
							var exception = (JContainer)JsonConvert.DeserializeObject(data);
							throw new JsdlException(
								exception["code"] != null ? exception["code"].ToString() : null, 
								exception["message"] != null ? exception["message"].ToString() : "", 
								exception["stackTrace"] != null ? exception["stackTrace"].ToString() : null);
						} catch { }
					}
					throw new JsdlException("http_" + (int)httpStatusCode, "HTTP error: " + httpStatusCode, null);
				}
			return JsonConvert.DeserializeObject<Person>(data);
		}
		
		public async Task UpdatePersonAsync(Person _person)
		{
			var url = BaseUrl + "/JsdlServices/DataService?operation=UpdatePerson&";
		
			var parameters = new List<object>();
			parameters.Add(_person);
		
			var content = new StringContent(JsonConvert.SerializeObject(parameters));
			
			var client = new HttpClient();
			PrepareRequest(client);
			var response = await client.PostAsync(url, content);
			ProcessResponse(client, response);
			var data = await response.Content.ReadAsStringAsync(); 
			var httpStatusCode = response.StatusCode;
			var isError = (int)httpStatusCode >= 400; 
			
				if (isError)
				{
					if (!string.IsNullOrEmpty(data))
					{
						try
						{
							var exception = (JContainer)JsonConvert.DeserializeObject(data);
							throw new JsdlException(
								exception["code"] != null ? exception["code"].ToString() : null, 
								exception["message"] != null ? exception["message"].ToString() : "", 
								exception["stackTrace"] != null ? exception["stackTrace"].ToString() : null);
						} catch { }
					}
					throw new JsdlException("http_" + (int)httpStatusCode, "HTTP error: " + httpStatusCode, null);
				}
			
		}
		
		
		
	}
	
	

}